package multiIntro;

import java.util.LinkedList;
import java.util.List;

import multiIntro.BlockEval;
import polyglot.ast.Block;
import polyglot.ast.ClassMember;
import polyglot.ast.Node;
import polyglot.ast.NodeFactory;
import polyglot.ast.TypeNode;
import polyglot.lex.Identifier;
import polyglot.types.Flags;
import polyglot.types.TypeSystem;
import polyglot.util.TypedList;
import xaj.xc.ast.ListNode;
import xaj.xc.ast.XAJNodeFactory;
import abc.aspectj.ast.IntertypeMethodDecl;

importsymbol multiIntro.BlockEval;

public syntaxclass MultiIntro /*extends Term_c implements IntertypeDecl*/ {
	@grammar extends intertype_member_declaration using BlockEval {
		MultiIntro ->
		m = modifiers_opt
		t = type
		id1 = IDENTIFIER
		"+." id2 = IDENTIFIER
		"(" p = formal_parameter_list_opt ")"
		b = BlockEval
		|
		m = modifiers_opt
		"void"
		id1 = IDENTIFIER
		"+." id2 = IDENTIFIER
		"(" p = formal_parameter_list_opt ")"
		b = BlockEval;		
	}
	
	private static String className;

	// retorna nome da classe corrente
	public static String getClassName() {
		return className;
	}
	
	public Node desugar(NodeFactory ft, TypeSystem ts) {
/*		XAJNodeFactory nf = (XAJNodeFactory) ft;
		
		//Procura todas as classe que são subtipos de id1 (Expr no exemplo visitorxaj)
		//Para este exemplo, eu estou fazendo manualmente, porém
		//é necessário criar uma biblioteca para realizar essa operação
		// na AST.
		TypeNode sum, mult, number;		
		sum = nf.AmbTypeNode(position(), "Sum");
		mult = nf.AmbTypeNode(position(), "Mult");
		number = nf.AmbTypeNode(position(), "Number");
		
		//Para cada subclasse um introduced é construido
		IntertypeMethodDecl suminter, multinter, numberinter;
		
		Flags modifiers = (Flags) get("m");
		TypeNode type;
		if(get("t") != null)
			type = (TypeNode) get("t");
		else
			type = nf.CanonicalTypeNode(position(), ts.Void());
		// Isso muda com o Eval
		String name = ((Identifier) get("id2")).getIdentifier();
		List param = (List) get("p");
		Block block = (Block) (((BlockEval)get("b")).desugar(ft, ts));
		
		List sumth = new TypedList(new LinkedList(), TypeNode.class, false);
		
		
		suminter = nf.IntertypeMethodDecl(position(), modifiers, type, sum,
				name, param, sumth, block);
		
		List multth = new TypedList(new LinkedList(), TypeNode.class, false);
		multinter = nf.IntertypeMethodDecl(position(), modifiers, type, mult,
				name, param, multth, block);
		
		List numberth = new TypedList(new LinkedList(), TypeNode.class, false);
		numberinter = nf.IntertypeMethodDecl(position(), modifiers, type, number,
				name, param, numberth, block);
		
		List list = new TypedList(new LinkedList(), ClassMember.class, false);
		list.add(suminter);
		list.add(multinter);
		list.add(numberinter);
		
		//Criar um novo Nó do tipo Lista
		ListNode listnode = nf.ListNode(position(), list);
		
		return listnode;*/
		return null;
	}
}
